<template>
  <div style="height: 100%;width:100%;">
    <div class="chart2" :style="{height: chartheight}"></div>
  </div>
  
</template>

<script lang="ts" setup>
  import { init, dispose, registerOverlay, registerIndicator, registerFigure, TooltipIconPosition } from 'klinecharts'
  import { getCurrentUserId } from '../../utils/currentUser.js'
  import { ref, onMounted, onUnmounted, defineProps, h } from 'vue';
  import { message } from 'ant-design-vue';
  import { nextTick } from 'vue';
  import { dateFormat, numberFormat, NumberUnit } from './tools.js'
  import {getDateOffsetFormat, getDateOffsetFormat2} from './date_utils.js';
  import { getSectorKlineData, getStockRsStrong } from '/@/api/stock/klineDataDao';

  defineExpose({switchSectorKlineData, switchPeriod, reInitChart});

  const pageHeight = ref(500);
  const chartheight = ref("200px");
  const chart = ref(null);
  const candleBarClickTime = ref(-1);
  const candlerBarData = ref({});
  const indicatorSettingModalParams = ref([]);
  const showIndicatorSettingModalParams = ref(false);
  var selectedMainIndicator = ref([]);
  var selectedSubIndicator = ref(['VOL']);
  const dateRange = ref({
    startDate: getDateOffsetFormat(-365),
    endDate: getDateOffsetFormat(0)
  });
  const currentPeriod = ref('Day');
  const currentSectorName = ref('');
  const indicatorSetting = ref(false);
  const baseSetting = ref(false);
  const dataLoading = ref(true);
  
  const subIndicatorMap = {};
  const mainIndicatorMap = {};

  const emit = defineEmits(['settingChange']);

  function initChart() {
    let chartDom = document.getElementsByClassName('chart2')[0];
    chart.value = init(chartDom, {
        customApi: {
          formatDate(_dateTimeFormat: Intl.DateTimeFormat, timestamp, _format: string, _type: FormatDateType) {
            return dateFormat(new Date(timestamp), "yyyy-MM-dd");
          }
        },
        locale: "zh-CN",
        styles: {
          indicator:{
            ohlc:{
              upColor: '#F92855',
              downColor: '#2DC08E',
              noChangeColor: '#888888'
            },
            bars: [{
              style: 'fill',
              borderStyle: 'solid',
              borderSize: 1,
              borderDashedValue: [2, 2],
              upColor: '#F92855',
              downColor: '#2DC08E',
              noChangeColor: '#888888'
            }]
          },
          candle: {
            bar: {
              upColor: '#F92855',
              downColor: '#2DC08E',
              noChangeColor: '#888888',
              upBorderColor: '#F92855',
              downBorderColor: '#2DC08E',
              noChangeBorderColor: '#888888',
              upWickColor: '#F92855',
              downWickColor: '#2DC08E',
              noChangeWickColor: '#888888'
            },
            tooltip: {
              custom: ({current}: { current: any }) => {
                return [
                  {title: "time", value: "{time}"},
                  {title: "open", value: "{open}"},
                  {title: "high", value: "{high}"},
                  {title: "low", value: "{low}"},
                  {title: "close", value: "{close}"},
                  {title: "成交额：", value: numberFormat(current.turnover, 2, NumberUnit.Yi)},
                  {title: "换手率：", value: current.turnoverRate + "%"},
                  {title: "涨跌幅：", value: current.riseAndFall + "%"}
                ];
              },
            }
          }
        }
      });


      selectedSubIndicator.value?.forEach(indicator => {
        addSubIndicator(indicator)
      });
      chart.value?.zoomAtCoordinate(2);
      chart.value?.setStyles({
        indicator: {
          tooltip: {
            icons: [
              {
                id: "visible",
                position: TooltipIconPosition.Middle,
                marginLeft: 8,
                marginTop: 2,
                marginRight: 0,
                marginBottom: 0,
                paddingLeft: 0,
                paddingTop: 0,
                paddingRight: 0,
                paddingBottom: 0,
                icon: "\ue903",
                fontFamily: "icomoon",
                size: 14,
                color: "#76808F",
                activeColor: "#76808F",
                backgroundColor: "transparent",
                activeBackgroundColor: "rgba(22, 119, 255, 0.15)"
              },
              {
                id: "invisible",
                position: TooltipIconPosition.Middle,
                marginLeft: 8,
                marginTop: 2,
                marginRight: 0,
                marginBottom: 0,
                paddingLeft: 0,
                paddingTop: 0,
                paddingRight: 0,
                paddingBottom: 0,
                icon: "\ue901",
                fontFamily: "icomoon",
                size: 14,
                color: "#76808F",
                activeColor: "#76808F",
                backgroundColor: "transparent",
                activeBackgroundColor: "rgba(22, 119, 255, 0.15)"
              },
              {
                id: "setting",
                position: TooltipIconPosition.Middle,
                marginLeft: 6,
                marginTop: 2,
                marginBottom: 0,
                marginRight: 0,
                paddingLeft: 0,
                paddingTop: 0,
                paddingRight: 0,
                paddingBottom: 0,
                icon: "\ue902",
                fontFamily: "icomoon",
                size: 14,
                color: "#76808F",
                activeColor: "#76808F",
                backgroundColor: "transparent",
                activeBackgroundColor: "rgba(22, 119, 255, 0.15)"
              },
              {
                id: "close",
                position: TooltipIconPosition.Middle,
                marginLeft: 6,
                marginTop: 2,
                marginRight: 0,
                marginBottom: 0,
                paddingLeft: 0,
                paddingTop: 0,
                paddingRight: 0,
                paddingBottom: 0,
                icon: "\ue900",
                fontFamily: "icomoon",
                size: 14,
                color: "#76808F",
                activeColor: "#76808F",
                backgroundColor: "transparent",
                activeBackgroundColor: "rgba(22, 119, 255, 0.15)"
              }
            ]
          }
        }
      });

      chart.value?.subscribeAction('onCandleBarClick', (data)=> {
        let now = Date.now();
        candleBarClickTime.value = now;
        candlerBarData.value = data;
      });

      chart.value?.subscribeAction('onTooltipIconClick', (data) => {
        if (data.indicatorName) {
          switch (data.iconId) {
            case "visible": {
              chart.value?.overrideIndicator({name: data.indicatorName, visible: true}, data.paneId);
              break;
            }
            case "invisible": {
              chart.value?.overrideIndicator({name: data.indicatorName, visible: false}, data.paneId);
              break;
            }
            case "setting": {
              const indicator = chart.value?.getIndicatorByPaneId(data.paneId, data.indicatorName);
              var settingData = {
                visible: true, 
                indicatorName: data.indicatorName, 
                paneId: data.paneId, 
                calcParams: indicator.calcParams
              }
              indicatorSettingModalParams.value = [settingData];
              showIndicatorSettingModalParams.value = true;
              break;
            }
            case "close": {
              if (data.paneId === "candle_pane") {
                chart.value?.removeIndicator("candle_pane", data.indicatorName);
                selectedMainIndicator.value = [...selectedMainIndicator.value.filter(item=>item!=data.indicatorName)]
              } else {
                chart.value?.removeIndicator(data.paneId, data.indicatorName);
                selectedSubIndicator.value = [...selectedSubIndicator.value.filter(item=>item!=data.indicatorName)]
              }
              break;
            }
            default:
              return;
          }
        }
      });

      chart.value?.setLoadDataCallback(({type, data, callback}) => {
        if(currentPeriod.value=='Day') {
          if (type === 'forward') {
            dateRange.value.endDate = dateRange.value.startDate;
            dateRange.value.startDate = getDateOffsetFormat2(dateRange.value.startDate, -365);
            dataLoading.value = true;
            getSectorKlineData({
              groupName: data.groupName,
              period: 'Day',
              startDate: dateRange.value.startDate,
              endDate: dateRange.value.endDate
            }).then(res => {
              dataLoading.value = false;
              let data = res['data'];
              let resultCode = res['resultCode'];
              let msg = res['msg'];
              if(resultCode=='FAIL') {
                message.error(msg)
                return;
              }
              callback(data, data.length > 0);
            });
          } else if(type=='backward') {
            if (dateRange.value.endDate === getDateOffsetFormat(0)) {
                callback([], false);
            }
          } else {
            callback([], true);
          }
        } else if(currentPeriod.value=='Week') {
          if (type === 'forward') {
            dateRange.value.endDate = dateRange.value.startDate;
            dateRange.value.startDate = getDateOffsetFormat2(dateRange.value.startDate, -1000);
            dataLoading.value = true;
            getSectorKlineData({
              groupName: data.groupName,
              period: 'Week',
              startDate: dateRange.value.startDate,
              endDate: dateRange.value.endDate
            }).then(res => {
              dataLoading.value = false;
              let data = res['data'];
              let resultCode = res['resultCode'];
              let msg = res['msg'];
              if(resultCode=='FAIL') {
                message.error(msg)
                return;
              }
              callback(data, data.length > 0);
            });
          } else if(type=='backward') {
            if (dateRange.value.endDate === getDateOffsetFormat(0)) {
                callback([], false);
            }
          } else {
            callback([], true);
          }
        } else {
          callback([], true);
        }
      });
  };

  function switchPeriod(period){
    currentPeriod.value = period;
    switchSectorKlineData(currentSectorName.value);
  }

  async function switchSectorKlineData(groupName) {
    if(!groupName) {
      return;
    }
    currentSectorName.value = groupName;
    dateRange.value.startDate = getDateOffsetFormat(-365);
    if(currentPeriod.value=='Week') {
      dateRange.value.startDate = getDateOffsetFormat(-1000);
    } else if(currentPeriod.value=='Month') {
      dateRange.value.startDate = getDateOffsetFormat(-36500);
    }
    dateRange.value.endDate = getDateOffsetFormat(0)
    dataLoading.value = true;
    let res = await getSectorKlineData({
      groupName: groupName,
      period: currentPeriod.value,
      startDate: dateRange.value.startDate,
      endDate: dateRange.value.endDate
    });
    let data = res['data'];
    let msg = res['msg'];
    let resultCode = res['resultCode'];
    dataLoading.value = false;
    if(resultCode=='FAIL'){
      message.error(msg);
      return;
    }
    if (data && data.length > 0) {
      settingItems.value.forEach(data=> {
        onSettingChange(data.key, data.value);
      });
      chart.value?.applyNewData(data);
      chart.value?.scrollToDataIndex(chart.value?.getDataList().length - 1);
    }
  };

  function onSettingChange(key, value) {
    let style = {};
    let keys = key.split(".");
    keys.reduce((p, c, i) => {
      if (i === keys.length - 1) {
        p[c] = value;
      } else {
        p[c] = {};
      }
      return p[c];
    }, style);

    chart.value?.setStyles(style);
    emit('settingChange', settingItems.value);
  };

  const settingItems = ref([]);

  const mainIndicator = [
    "MA", "EMA", "SMA", "BOLL", "SAR", "BBI",
    "stockWeighted8dRS",
    "stockWeighted12dRS",
    "stockWeighted24dRS",
    "stockWeighted44dRS",
    "stockWeighted64dRS",
    "stockWeighted128dRS",
    "stockWeighted252dRS",
  ];


  const subIndicator = [
    "MA", "EMA", "VOL", "MACD", "BOLL", "KDJ",
    "RSI", "BIAS", "BRAR", "CCI", "DMI",
    "CR", "PSY", "DMA", "TRIX", "OBV",
    "VR", "WR", "MTM", "EMV", "SAR",
    "SMA", "ROC", "PVT", "BBI", "AO"
  ];

  const indicatorMap: Record<string, string> = {
    "ma": "MA(移动平均线)",
    "ema": "EMA(指数平滑移动平均线)",
    "sma": "SMA",
    "boll": "BOLL(布林线)",
    "bbi": "BBI(多空指数)",
    "sar": "SAR(停损点指向指标)",
    "vol": "VOL(成交量)",
    "macd": "MACD(指数平滑异同移动平均线)",
    "kdj": "KDJ(随机指标)",
    "rsi": "RSI(相对强弱指标)",
    "bias": "BIAS(乖离率)",
    "brar": "BRAR(情绪指标)",
    "cci": "CCI(顺势指标)",
    "dmi": "DMI(动向指标)",
    "cr": "CR(能量指标)",
    "psy": "PSY(心理线)",
    "dma": "DMA(平行线差指标)",
    "trix": "TRIX(三重指数平滑平均线)",
    "obv": "OBV(能量潮指标)",
    "vr": "VR(成交量变异率)",
    "wr": "WR(威廉指标)",
    "mtm": "MTM(动量指标)",
    "emv": "EMV(简易波动指标)",
    "roc": "ROC(变动率指标)",
    "pvt": "PVT(价量趋势指标)",
    "ao": "AO(动量震荡指标)",
    "stockweighted8drs": "8日 IBD_RS",
    "stockweighted12drs": "半月 IBD_RS",
    "stockweighted24drs": "1月 IBD_RS",
    "stockweighted44drs": "2月 IBD_RS",
    "stockweighted64drs": "3月 IBD_RS",
    "stockweighted128drs": "6月 IBD_RS",
    "stockweighted252drs": "1年 IBD_RS"
  };

  /**
   * 添加副指标
   */
  function addSubIndicator(indicatorName) {
    var indicator;
    let subHeight = (pageHeight.value / 9).toFixed(0);
    subHeight = (parseInt(subHeight) / 2).toFixed(0);
    if(indicatorName=='VOL') {
      indicator = chart.value?.createIndicator({name:indicatorName,calcParams:[50]}, 
        false, {calcParams: [50],height:parseInt(subHeight)});
    } else {
      indicator = chart.value?.createIndicator(indicatorName, false, {height: parseInt(subHeight)});
    }
    subIndicatorMap[indicatorName] = indicator;
    if (!selectedSubIndicator.value.includes(indicatorName)) {
      selectedSubIndicator.value.push(indicatorName);
    }
  }

  function reInitChart(){
    let chartDom = document.getElementsByClassName('chart2')[0];
    dispose(chartDom);
    initChart();
  }

  onMounted(async ()=> {
    pageHeight.value = window.innerHeight;
    chartheight.value = ((pageHeight.value  - 100) * 0.4 - 40) +'px';
    initChart();
  });
</script>